
#include <memory>
#include <algorithm>
#include <string>
#include <iostream>

#include "audioproc_float_impl2.h"
#include "api/audio/audio_processing.h"
#include "common_audio/wav_header.h"
#include "common_audio/channel_buffer.h"
#include "common_audio/wav_file.h"

namespace webrtc {
namespace test {
// we don't apply 
int AudioprocFloatImpl2(int argc, char* argv[]) {
  auto ap = AudioProcessingBuilder().Create();
  
  webrtc::AudioProcessing::Config config;
  config.echo_canceller.delay_ms = 2000;
  config.echo_canceller.enabled = false;
  config.noise_suppression.enabled = false;
  config.gain_controller1.enabled = true;
  

  if (argc < 4) {
    std::cout << argv[0] << " /xx/mic.wav /xx/lpb.wav /xx/res.wav" << std::endl;
  }
  

  std::string in_path = argv[1];
  auto in_file = std::make_unique<WavReader>(in_path.c_str());

  size_t channels = in_file->num_channels();
  int sample_rate_hz = in_file->sample_rate();
  size_t samples = in_file->num_samples();
  size_t samples_per_frame = sample_rate_hz / 100;

  
  std::string reverse_in_path = argv[2];
  auto reverse_file = std::make_unique<WavReader>(reverse_in_path.c_str());
  size_t reverse_channels = reverse_file->num_channels();
  int reverse_sample_rate_hz = reverse_file->sample_rate();
  size_t reverse_samples = reverse_file->num_samples();
  size_t reverse_samples_per_frame = reverse_sample_rate_hz / 100;

  if (in_path.compare(reverse_in_path) == 0) {
    // capture and render is the sample, so we close the aec
    config.echo_canceller.enabled = false;
  }

  std::string out_file_path = argv[3];
  auto out_file = std::make_unique<WavWriter>(out_file_path.c_str(), sample_rate_hz, channels);


  std::cout << "channels: " << channels << ", sample rate: " << sample_rate_hz << ", duration: " << (float)samples / sample_rate_hz << " seconds" << std::endl;
  std::cout << "reverse channels: " << reverse_channels << ", sample rate: " << reverse_sample_rate_hz << ", duration: " << (float)reverse_samples / sample_rate_hz << " seconds" << std::endl;

  int frames = int((float)samples / sample_rate_hz * 100.f);

  std::unique_ptr<int16_t[]> in_buf(new int16_t[samples_per_frame * channels]);
  std::unique_ptr<int16_t[]> reverse_in_buf(new int16_t[reverse_samples_per_frame * channels]);
  
  ap->ApplyConfig(config);
  for (int i = 0; i < frames; i++) {
    in_file->ReadSamples(samples_per_frame, in_buf.get());
    if (reverse_file->ReadSamples(reverse_samples_per_frame, reverse_in_buf.get()) != reverse_samples_per_frame) {
      memset(reverse_in_buf.get(), 0, reverse_samples_per_frame * channels * sizeof(int16_t));
    }
    memset(reverse_in_buf.get(), 0, reverse_samples_per_frame * channels * sizeof(int16_t));

    // Reverse 
    StreamConfig reverse_input_config(reverse_sample_rate_hz, reverse_channels);
    StreamConfig reverse_output_config(reverse_sample_rate_hz, reverse_channels);
    ap->ProcessReverseStream(reverse_in_buf.get(), reverse_input_config, reverse_output_config, reverse_in_buf.get());

    ap->set_stream_delay_ms(0);
    ap->set_stream_key_pressed(false);
 
    // Primary
    StreamConfig input_config(sample_rate_hz, channels);
    StreamConfig output_config(sample_rate_hz, channels);
    ap->ProcessStream(in_buf.get(), input_config, output_config, in_buf.get());

    out_file->WriteSamples(in_buf.get(), samples_per_frame);
  }
  return 0;
}
} // namespace test
} // namespace webrtc
